﻿using System;
using Assignment_2.Entities.Components;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Assignment_2.Entities
{
    class Typhoon : Entity
    {
        public Matrix[] BoneTransforms { get; set; }

        private Matrix _baseLeftLegTransform { get; set; }
        private Matrix _baseLeftCalfTransform { get; set; }
        private Matrix _baseLeftShoulderTransform { get; set; }
        private Matrix _baseLeftBicepTransform { get; set; }
        private Matrix _baseLeftWristTransform { get; set; }

        private Matrix _baseRightLegTransform;
        private Matrix _baseRightCalfTransform;
        private Matrix _baseRightShoulderTransform;
        private Matrix _baseRightBicepTransform;
        private Matrix _baseRightWristTransform;

        private Game1 _game;

        private float _rightLegRotation;
        private float _leftLegRotation;
        private float _rightShoulderRotation;
        private float _leftShoulderRotation;

        private int _steps = 0;
        private int _stepLimit = 10;
        private int _mode = 1;

        // *** LEGS ***
        // Left
        private float _left_thigh_rot_X = MathHelper.WrapAngle(-20f);
        private float _left_calf_rot_X = MathHelper.WrapAngle(0.5f);

        // Right
        private float _right_thigh_rot_X = MathHelper.WrapAngle(20f);
        private float _right_calf_rot_X = MathHelper.WrapAngle(-0.5f);

        // *** ARMS *** 
        // Left
        private float _left_shoulder_rot_Y = -10;
        private float _left_shoulder_rot_Z = -20f;
        private float _left_bicep_rot_X = -8f;
        private float _left_bicep_tra_X = -0.1f;
        private float _left_bicep_tra_Y = -0.2f;
        private float _left_bicep_tra_Z = -0.2f;
        private float _left_wrist_rot_Y = 55f;
        private float _left_wrist_tra_X = -0.0f;
        private float _left_wrist_tra_Z = 0.1f;

        // Right
        private float _right_shoulder_rot_Y = MathHelper.WrapAngle(10f);
        private float _right_shoulder_rot_Z = MathHelper.WrapAngle(-20f);
        private float _right_bicep_rot_X = MathHelper.WrapAngle(-8f);
        private float _right_bicep_tra_X = MathHelper.WrapAngle(-0.1f);
        private float _right_bicep_tra_Y = MathHelper.WrapAngle(-0.2f);
        private float _right_bicep_tra_Z = MathHelper.WrapAngle(-0.2f);
        private float _right_wrist_rot_Y = MathHelper.WrapAngle(43f);
        private float _right_wrist_tra_X = MathHelper.WrapAngle(-0.0f);
        private float _right_wrist_tra_Z = MathHelper.WrapAngle(0.1f);


        // Model parts
        public float RightLegRotation
        {
            get { return _rightLegRotation; }
            set { _rightLegRotation = MathHelper.WrapAngle(value); }
        }

        public float LeftLegRotation
        {
            get { return _leftLegRotation; }
            set { _leftLegRotation = MathHelper.WrapAngle(value); }
        }

        public float RightShoulderRotation
        {
            get { return _rightShoulderRotation; }
            set { _rightShoulderRotation = MathHelper.WrapAngle(value); }
        }

        public float LeftShoulderRotation
        {
            get { return _leftShoulderRotation; }
            set { _leftShoulderRotation = MathHelper.WrapAngle(value); }
        }

        public Typhoon(GraphicsDevice device, Game1 game, Model model)
        {
            DrawComponents.Add(EntityNames.Typhoon, new ModelComponent(this, device, game, model));
            _game = game;

            BoneTransforms = new Matrix[((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones.Count];

            _baseRightLegTransform = ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["right_thigh"].Transform;
            _baseRightCalfTransform = ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["right_calf"].Transform;
            _baseRightShoulderTransform = ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_shoulder01"].Transform;
            _baseRightBicepTransform = ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_biceps02"].Transform;
            _baseRightWristTransform = ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_wrist02"].Transform;
            _baseLeftLegTransform = ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["right_thigh01"].Transform;
            _baseLeftCalfTransform = ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["right_calf01"].Transform;
            _baseLeftShoulderTransform = ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_shoulder"].Transform;
            _baseLeftBicepTransform = ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_biceps"].Transform;
            _baseLeftWristTransform = ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_wrist"].Transform;

            Initialize();
            Rotation = Matrix.CreateRotationX(0) * Matrix.CreateRotationY(0f) * Matrix.CreateRotationZ(0);
        }


        public void Initialize()
        {
            // *** LEGS *** 
            // Left
            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["right_thigh01"].Transform = Matrix.CreateRotationX(_left_thigh_rot_X) * _baseLeftLegTransform;
            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["right_calf01"].Transform = Matrix.CreateRotationX(_left_calf_rot_X) * _baseLeftCalfTransform;
            _baseLeftLegTransform = ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["right_thigh01"].Transform;
            
            // Right
            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["right_thigh"].Transform = Matrix.CreateRotationX(_right_thigh_rot_X) * _baseRightLegTransform;
            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["right_calf"].Transform = Matrix.CreateRotationX(_right_calf_rot_X) * _baseRightCalfTransform;
            _baseRightLegTransform = ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["right_thigh"].Transform;

            // *** ARMS *** 
            // Left
            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_shoulder"].Transform = Matrix.CreateRotationY(_left_shoulder_rot_Y) * _baseLeftShoulderTransform;
            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_shoulder"].Transform = Matrix.CreateRotationZ(_left_shoulder_rot_Z) * _baseLeftShoulderTransform;
            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_biceps"].Transform = Matrix.CreateRotationX(_left_bicep_rot_X) * _baseLeftBicepTransform;
            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_biceps"].Transform = Matrix.CreateTranslation(_left_bicep_tra_X, _left_bicep_tra_Y, _left_bicep_tra_Z) * _baseLeftBicepTransform;
            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_wrist"].Transform = Matrix.CreateRotationY(_left_wrist_rot_Y) * _baseLeftWristTransform;
            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_wrist"].Transform = Matrix.CreateTranslation(_left_wrist_tra_X, 0.0f, _left_wrist_tra_Z) * _baseLeftWristTransform; ;
            _baseLeftShoulderTransform = ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_shoulder"].Transform;

            // Right
            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_shoulder01"].Transform = Matrix.CreateRotationY(_right_shoulder_rot_Y) * _baseRightShoulderTransform;
            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_shoulder01"].Transform = Matrix.CreateRotationZ(_right_shoulder_rot_Z) * _baseRightShoulderTransform;
            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_biceps02"].Transform = Matrix.CreateRotationX(_right_bicep_rot_X) * _baseRightBicepTransform;
            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_biceps02"].Transform = Matrix.CreateTranslation(_right_bicep_tra_X, _right_bicep_tra_Y, _right_bicep_tra_Z) * _baseRightBicepTransform;
            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_wrist02"].Transform = Matrix.CreateRotationY(_right_wrist_rot_Y) * _baseRightWristTransform;
            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_wrist02"].Transform = Matrix.CreateTranslation(_right_wrist_tra_X, 0.0f, _right_wrist_tra_Z) * _baseRightWristTransform;
            _baseRightShoulderTransform = ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_shoulder01"].Transform;

            // ???
            //((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.CopyAbsoluteBoneTransformsTo(BoneTransforms);
        }

        public override void Update(GameTime gt, Matrix parentMatrix)
        {
            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Root.Transform = Matrix.Identity *
                                   Matrix.CreateScale(1f) *
                                   Rotation *
                                   Matrix.CreateTranslation(((World)_game.Entities[EntityNames.World]).ConvertToSphere(Position));

            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["right_thigh"].Transform = Matrix.CreateRotationX(RightLegRotation) * _baseRightLegTransform;
            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["right_thigh01"].Transform = Matrix.CreateRotationX(LeftLegRotation) * _baseLeftLegTransform;

            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_shoulder"].Transform = Matrix.CreateRotationY(LeftShoulderRotation) * _baseLeftShoulderTransform;
            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.Bones["left_shoulder01"].Transform = Matrix.CreateRotationY(RightShoulderRotation) * _baseRightShoulderTransform;

            ((ModelComponent)DrawComponents[EntityNames.Typhoon]).Model.CopyAbsoluteBoneTransformsTo(BoneTransforms);

            base.Update(gt, parentMatrix);
        }

        public void WalkAnimation()
        {
            _steps += 1;
            if (_steps == _stepLimit)
            {
                _mode = (_mode == 1) ? 0 : 1;
                _steps = 0;
            }
                switch (_mode)
                {
                    case 0:
                        RightLegRotation += 0.05f;
                        LeftLegRotation -= 0.05f;
                        RightShoulderRotation -= 0.05f;
                        LeftShoulderRotation += 0.05f;
                        break;
                    case 1:
                        RightLegRotation -= 0.05f;
                        LeftLegRotation += 0.05f;
                        RightShoulderRotation += 0.05f;
                        LeftShoulderRotation -= 0.05f;
                        break;
                }
        }



    }
}
